#include "store/chunk.h"
#include "bytes.h"
#include "util.h"
#include <fcntl.h>
#include <errno.h>
#include <memory.h>
#include <stdio.h>

const size_t CACHE_BUFFER_COUNT=16;
const size_t CACHE_BUFFER_SIZE=4096;

int chunk_repair_rdfd(struct store_chunk *chunk){
	int rd=open(chunk->name,O_RDONLY);
	if(rd==-1){
		return -1;	
	}
	chunk->rd_fd=rd;
	lseek(rd,chunk->rd_index,SEEK_SET);
	return 0;
}

int chunk_repair_wrfd(struct store_chunk *chunk){
	int wd=open(chunk->name,O_WRONLY|O_APPEND);
	if(wd==-1){
		return -1;	
	}
	lseek(wd,chunk->wr_index,SEEK_SET);
	chunk->wr_fd=wd;
	return 0;
}

int write_data(struct store_chunk *chunk,struct buffer *buff){
	int fd=chunk->wr_fd;
	unsigned long off_wr=chunk->wr_index;
	
	ready_to_write(buff);
	char *data_ref=buff->data;
	int wr_len= buff->limit - buff->index;
	while(wr_len){
		int ret=write(fd,data_ref + buff->index,wr_len);
		if(ret == -1){
			if(errno==EAGAIN){continue;}
			if(errno==EINTR){continue;}
			chunk->wr_index=off_wr;
			close(fd);
			return -1;
		}
		if(ret == 0){
			continue ;
		}
		chunk->wr_index = chunk->wr_index + ret;	
		if(ret == wr_len){
			return 0;
		}
		wr_len = wr_len - ret;
		buff->index =  buff->index + ret;
	}
	return 0;
}



int read_data_unitHead(struct store_chunk *chunk,struct buffer *buff){
	int fd=chunk->rd_fd;
	unsigned long off_rd=chunk->rd_index;//将这个放到外面在读完一个后再设置
	
	char *data_ref=buff->data;
	buff->limit=2;
	int rd_len= 2 - buff->index;

	while(rd_len){
		int ret=read(fd,data_ref + buff->index,rd_len);
		if(ret == -1){
			if(errno==EAGAIN){continue;}
			if(errno==EINTR){continue;}
			chunk->rd_index=off_rd;
			close(fd);
			return -1;
		}
		if(ret == 0){
			chunk->rd_index=off_rd;
			return 1;
		}
		rd_len = rd_len - ret;
		buff->index =  buff->index + ret;
	}
	return 0;
}

int read_data_unitBody(struct store_chunk *chunk,struct buffer *buff){
	int fd = chunk->rd_fd;
	unsigned long off_rd=chunk->rd_index;
	int rd_len= buff->limit;
	char *data_ref=buff->data;

	while(rd_len){
		int ret=read(fd,data_ref + buff->index,rd_len);
		if(ret == -1){
			if(errno==EAGAIN){continue;}
			if(errno==EINTR){continue;}
			chunk->rd_index=off_rd;
			close(fd);
			return -1;
		}
		if(ret == 0){
			chunk->rd_index=off_rd;
			return 1;
		}
		rd_len = rd_len - ret;
		buff->index =  buff->index + ret;
	}
	return 0;
}

int read_data(struct store_chunk *chunk,struct buffer *buff,int unit_begin){
	if(unit_begin){
		int ret=read_data_unitHead(chunk,buff);
		return ret;
	}
	return read_data_unitBody(chunk,buff);
}

